package com.nulldev.util.data.Images;

import java.awt.Color;

import com.nulldev.util.VariableAPI.MathUtil;
import com.nulldev.util.VariableAPI.RandomUtil;

public class ColorUtil {
	public static final Color TRANSPARENT = new Color(0, 0, 0, 0);

	public static final Color LIGHT_BLUE = new Color(90, 228, 211);

	public static final Color GREEN = new Color(0, 128, 0);

	public static Color invertBAD(final Color color) {
		final int r = 255 - color.getRed();
		final int g = 255 - color.getBlue();
		final int b = 255 - color.getGreen();
		return new Color(r, g, b);
	}

	public static Color invertd(final Color color) {
		final int r = 255 - color.getRed();
		final int g = 255 - color.getBlue();
		final int b = 255 - color.getGreen();
		return lighten(new Color(r, g, b), 4);
	}

	public static Color split(final Color color) {
		final int lum = getLuminance(color.getRGB());
		if (lum <= 128) {
			return darken(color, 2);
		} else {
			return lighten(color, 2);
		}
	}

	public static int getLuminance(final int argb) {
		final int lum = (77 * ((argb >> 16) & 255) + 150 * ((argb >> 8) & 255) + 29 * ((argb) & 255)) >> 8;
		return lum;
	}

	public static Color invert(final Color color) {
		return new Color((0xFFFFFF - color.getRGB()) | 0xFF000000);
	}

	public static Color darken(final Color color, final double fraction) {
		int red = (int) Math.round(color.getRed() * (1.0 - fraction));
		int green = (int) Math.round(color.getGreen() * (1.0 - fraction));
		int blue = (int) Math.round(color.getBlue() * (1.0 - fraction));
		if (red < 0) {
			red = 0;
		} else if (red > 255) {
			red = 255;
		}
		if (green < 0) {
			green = 0;
		} else if (green > 255) {
			green = 255;
		}
		if (blue < 0) {
			blue = 0;
		} else if (blue > 255) {
			blue = 255;
		}
		final int alpha = color.getAlpha();
		return new Color(red, green, blue, alpha);
	}

	public static Color lighten(final Color color, final double fraction) {
		int red = (int) Math.round(color.getRed() * (1.0 + fraction));
		int green = (int) Math.round(color.getGreen() * (1.0 + fraction));
		int blue = (int) Math.round(color.getBlue() * (1.0 + fraction));
		if (red < 0) {
			red = 0;
		} else if (red > 255) {
			red = 255;
		}
		if (green < 0) {
			green = 0;
		} else if (green > 255) {
			green = 255;
		}
		if (blue < 0) {
			blue = 0;
		} else if (blue > 255) {
			blue = 255;
		}
		final int alpha = color.getAlpha();
		return new Color(red, green, blue, alpha);
	}

	public static String toHex(final Color color) {
		return MathUtil.toHex(color.getRGB());
	}

	public static Color randomColorWithTransparency() {
		return new Color(MathUtil.clamp(0, 255, RandomUtil.randInt(0, 255)), MathUtil.clamp(0, 255, RandomUtil.randInt(0, 255)),
				MathUtil.clamp(0, 255, RandomUtil.randInt(0, 255)));
	}

	public static Color randomColor() {
//		final int r = RandomUtil.randInt(0, 255), g = RandomUtil.randInt(0, 255), b = RandomUtil.randInt(0, 255), a = RandomUtil.randInt(40, 255);
//		JVM.println("\tr: " + r + ", g: " + g + ", b: " + b + ", a: " + a);
//		return new Color(r, g, b, a);
		return new Color(MathUtil.clamp(0, 255, RandomUtil.randInt(0, 255)), MathUtil.clamp(0, 255, RandomUtil.randInt(0, 255)),
				MathUtil.clamp(0, 255, RandomUtil.randInt(40, 255)));
	}

	public static Color randomColorMaxAlpha(final int alpha) {
		return new Color(MathUtil.clamp(0, 255, RandomUtil.randInt(0, 255)), MathUtil.clamp(0, 255, RandomUtil.randInt(0, 255)),
				MathUtil.clamp(0, 255, MathUtil.clamp(0, alpha, RandomUtil.randInt(40, 255))));
	}

	public static Color randomColor(final int alpha) {
		return new Color(RandomUtil.randInt(0, 255), RandomUtil.randInt(0, 255), RandomUtil.randInt(0, 255), MathUtil.clamp(0, 255, alpha));
	}

	public static Color rainbow(final long offset, final float fade) {
		final float hue = (System.nanoTime() + offset) / 1.0E10f % 1.0f;
		final long color = Long.parseLong(Integer.toHexString(Integer.valueOf(Color.HSBtoRGB(hue, 1.0f, 1.0f))), 16);
		final Color c = new Color((int) color);
		return new Color(c.getRed() / 255.0f * fade, c.getGreen() / 255.0f * fade, c.getBlue() / 255.0f * fade, c.getAlpha() / 255.0f);
	}

	public static Color rainbow(final long offset, final float fade, final float off) {
		final float hue = (System.nanoTime() + offset) / 1.0E10f % 1.0f;
		final long color = Long.parseLong(Integer.toHexString(Integer.valueOf(Color.HSBtoRGB(hue, 1.0f, 1.0f))), 16);
		final Color c = new Color((int) color);
		return new Color(MathUtil.clamp(0, 255, (c.getRed() + off)) / 255.0f * fade, MathUtil.clamp(0, 255, (c.getGreen() + off)) / 255.0f * fade,
				MathUtil.clamp(0, 255, (c.getBlue() + off)) / 255.0f * fade, c.getAlpha() / 255.0f);
	}

	public static String hexFromColor(final Color color) {
		return Integer.toHexString(color.getRGB()).substring(2);
	}

	public static int intFromColor(final Color color) {
		return intFromHex(hexFromColor(color));
	}

	public static int intFromHex(final String hex) {
		try {
			return Integer.parseInt(hex, 16);
		} catch (NumberFormatException ex) {
			return -1;
		}
	}

	public static String hexFromInt(int color) {
		if ((color & 0xFC000000) == 0x0) {
			color |= 0xFF000000;
		}
		return hexFromColor(new Color(color));
	}

	public static int getIntFromColor(int Red, int Green, int Blue) {
		Red = (Red << 16 & 0xFF0000);
		Green = (Green << 8 & 0xFF00);
		Blue &= 0xFF;
		return 0xFF000000 | Red | Green | Blue;
	}

	public static Color randomGray() {
		final int c = RandomUtil.randInt(0, 128);
		return new Color(c, c, c);
	}

	public static Color randomGray(final int alpha) {
		final int c = RandomUtil.randInt(0, 128);
		return new Color(c, c, c, MathUtil.clamp(0, 255, alpha));
	}
}
